/*
    热点管理模块：对服务器备份的文件进行检测，那些文件长时间未被访问则被压缩存储
		思路：遍历所有文件，直接获取所有文件的属性
			不采用遍历文件属性表是因为可能对文件进行操作时没有更新属性表，
			并且数据管理模块在访问文件之后并不会更新文件属性表，只有在更改文件时才会更新文件属性表
		流程：
			1、遍历备份文件，获取所有文件的路径
			2、获取所有文件的最后一次访问时间，与当前系统时间进行比较
			3、对非热点文件进行压缩，并删除原文件
			4、修改数据管理模块对应的文件信息 -- 压缩标志
		成员：
			1、文件目录
			2、压缩包目录
			3、热点时间
			4、压缩包后缀名
			5、数据管理对象的指针 -- 可写成全局变量，直接访问
		接口：
			1、构造函数
			2、运行流程

*/


#ifndef __M_HOT_H__
#define __M_HOT_H__

#include "dataController.hpp"

extern cloud::DataController *_data;

namespace cloud{
    class HotController{
    public:
        HotController(){
            //用单例类获取文件属性
            Config *config = Config::getInstance();
            _backup_dir = config->getBackupDir();
            _pack_dir = config->getPackDir();
            _packfile_suffix = config->getPackfileSuffix();
            _hot_time = config->getHotTime();

            //这两个目录可能不存在，不存在就创建
            FileUtil fu1(_backup_dir);
            FileUtil fu2(_pack_dir);
            fu1.createDirectory();
            fu2.createDirectory();
        }

        bool run(){
            while(1){
                // 1、遍历备份文件，获取所有文件的路径
                FileUtil allfu(_backup_dir);
                vector<string> arr;
                allfu.scanDirectory(&arr);

                // 2、获取所有文件的最后一次访问时间，与当前系统时间进行比较
                for(auto &a : arr){
                    if(!isHot(a)){
                        //3、对非热点文件进行压缩，并删除原文件
                        //3.1、获取文件属性
                        //数据信息结构体用来保存文件属性
                        BackupInfo info;
                        //通过文件路径在文件属性表中查找该文件，获取文件属性，传给info
                        if(_data->getByPath(a, &info) == false){
                            //走到这里代表找不到该文件，由于文件路径是直接从文件目录获取的，所以该文件一定存在
                            //找不到就代表虽然存在但是没有存放到文件属性表中 -- 漏添加
                            //这时就需要手动添加一次
                            info.fillNewInfo(a);
                        }
                        //3.2、进行压缩
                        FileUtil compressfu(a);
                        compressfu.compress(info._ppath);
                        //3.3、删除原文件，不能用数据管理者的remove，那个是直接删除文件而不是压缩后删除原文件
                        // _data->remove(info); -- err
                        compressfu.remove();

                        //4、修改数据管理模块对应的文件信息 -- 压缩标志
                        info._iscompressed = true;

                        //5、提交修改，更新文件属性表
                        _data->update(info);



                        // //3. 获取文件的备份信息
                        // BackupInfo info;
                        // if (_data->getByPath(a, &info) == false){
                        //     //现在有一个文件存在，但是没有备份信息
                        //     info.fillNewInfo(a);//设置一个新的备份信息出来
                        // }
                        // //3. 对非热点文件进行压缩处理
                        // FileUtil tmp(a);
                        // tmp.compress(info._ppath);
                        // //4. 删除源文件，修改备份信息
                        // tmp.remove();
                        // info._iscompressed = true;
                        // _data->update(info);





                        cout << "compress : " << info._fpath << endl;
                        cout << "packname : " << info._ppath << endl;
                    }
                }
                sleep(1);
            }
    }

    private:
        //热点文件返回true，非热点文件返回false
        bool isHot(const string& filename){
            FileUtil fu(filename);
            time_t latime = fu.lastAccessTime();
            time_t ctime = time(NULL);
            if(ctime - latime > _hot_time){
                return false;
            }
            return true;
        }

    private:
        string _backup_dir;
        string _pack_dir;
        string _packfile_suffix;
        int _hot_time;
    };
}




// namespace cloud{
// 	class HotController{
// 		private:
// 			std::string _back_dir;
// 			std::string _pack_dir;
// 			std::string _pack_suffix;
// 			int _hot_time;
// 		private:
// 			//非热点文件-返回真；热点文件-返回假
// 			bool HotJudge(const std::string &filename){
// 				FileUtil fu(filename);
// 				time_t last_atime = fu.lastAccessTime();
// 				time_t cur_time = time(NULL);
// 				if (cur_time - last_atime > _hot_time){
// 					return true;
// 				}
// 				return false;
// 			}
// 		public:
// 			HotController() {
// 				Config *config = Config::getInstance();
// 				_back_dir = config->getBackupDir();
// 				_pack_dir = config->getPackDir();
// 				_pack_suffix = config->getPackfileSuffix();
// 				_hot_time = config->getHotTime();
// 				FileUtil tmp1(_back_dir);
// 				FileUtil tmp2(_pack_dir);
// 				tmp1.createDirectory();
// 				tmp2.createDirectory();
// 			}
// 			bool run() {
// 				while(1){
// 					//1. 遍历备份目录，获取所有文件名
// 					FileUtil fu(_back_dir);
// 					std::vector<std::string> arry;
// 					fu.scanDirectory(&arry);
// 					//2. 遍历判断文件是否是非热点文件
// 					for (auto &a : arry) {
// 						if (HotJudge(a) == false){
// 							continue;//热点文件则不需要特别处理
// 						}
// 						//3. 获取文件的备份信息
// 						BackupInfo bi;
// 						if (_data->getByPath(a, &bi) == false){
// 							//现在有一个文件存在，但是没有备份信息
// 							bi.fillNewInfo(a);//设置一个新的备份信息出来
// 						}
// 						//3. 对非热点文件进行压缩处理
// 						FileUtil tmp(a);
// 						tmp.compress(bi._ppath);
// 						//4. 删除源文件，修改备份信息
// 						tmp.remove();
// 						bi._iscompressed = true;
// 						_data->update(bi);
// 					}
// 					usleep(1000);//避免空目录循环遍历，消耗cpu资源过高
// 				}
// 				return true;
// 			}
// 	};
// }

#endif
